﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Logistics.DataManage.Local;
using Logistics.DataManage.Server;
using Logistics.Utils;
using MapgisEbp.QuickDataBase;
using MapgisEbp.QuickDataBase.Common;

namespace Logistics.DataManage
{
    class CustomerDownloader : AbstractWorker
    {
        private const int PageSize = 5000;
        private bool isCancled = false;

        public override void DoWork()
        {
            DownloadCustomersAsyn();//DownloadCustomers();
        }

        public override void Cancle()
        {
            isCancled = true;
        }

        public void DownloadCustomersAsyn()
        {
            try
            {
                LogUtils.WriteLog("开始准备下载客户数据--DataDownloader");
                DownloadCustomers();
                LogUtils.WriteLog("客户数据下载完毕--DataDownloader");
                this.RaiseComplete();
            }
            catch (Exception ex)
            {
                LogUtils.WriteLog(ex.ToString());
                FailState state = new FailState() { FailedMsg = ex.ToString() };
                this.RaiseFail(state);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void DownloadCustomers()
        {
            try
            {
                string siteID = GetSiteID();
                int ServerTotalCount = RemoteDateServiceFactory.DateService.GetCustomerCount(siteID);
                LogUtils.WriteDebug(String.Format("服务器上总共有{0}条客户数据等待下载......", ServerTotalCount));
                if (ServerTotalCount == 0)
                {
                    LogUtils.WriteDebug(String.Format("没有客户数据需要下载，返回"));
                    return;
                }

                LocalDb.ExecuteNonQuery("delete from CustomsTemp");//清空临时表

                int total = 0;
                int pageIndex = 0;
                int lastResult = PageSize;
                while (lastResult == PageSize)
                {
                    if (isCancled)
                    {
                        LogUtils.WriteDebug("Download is Cancled!!");
                        return;
                    }
                    //获取服务器端数据
                    DataSet svrData = RemoteDateServiceFactory.DateService.GetCustomers(siteID, pageIndex, PageSize);
                    pageIndex++;
                    lastResult = (svrData == null ? 0 : svrData.Tables[0].Rows.Count);
                    total += lastResult;
                    LogUtils.WriteDebug(String.Format("第{0}次从服务器获取到{1}条客户数据", pageIndex,lastResult));
                    //将从服务器获取到的数据写入临时表
                    if (svrData != null && svrData.Tables[0].Rows.Count > 0)
                    {
                        StoreCustomersTemp(svrData);
                    }
                    int percent = Convert.ToInt32((((float)total) / ServerTotalCount) * 100);
                    String msg = String.Format("当前已下载处理{0},总共{1}",total,ServerTotalCount);
                    this.RaiseUpdate(new WorkState() { Process = percent, ProcessMsg = msg });
                }
                LogUtils.WriteDebug(String.Format("总共从服务器获取到{0}条客户数据,并已存入临时客户表中。", total));
                LogUtils.WriteDebug("准备从临时客户表读取数据到客户表......");
                TranslateCustomerData();
            }
            catch (Exception ex)
            {
                LogUtils.WriteError(ex.ToString());
                throw ex;
            }
        }
        /// <summary>
        /// 将服务器数据插入到本地临时表中
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public int StoreCustomersTemp(DataSet ds)
        {
            DataTable TemplateDt = LocalDb.TableTemplates["CustomsTemp"];
            IList<String> ColumnNames = DataDownloader.MappingLocalColumns(TemplateDt, ds.Tables[0]);
            String fieldNames = "";
            String values = "";
            foreach (String colName in ColumnNames)
            {
                fieldNames += colName + ",";
                values += "?,";
            }
            fieldNames = fieldNames.TrimEnd(',');
            values = values.TrimEnd(',');
            String sql = "INSERT INTO CustomsTemp(" + fieldNames + ")Values(" + values + ")";
            int rtn = 0;
            DataRowCollection DataRows = ds.Tables[0].Rows;
            int RowCount = DataRows.Count;
            int Size = 500; //每500条记录提交一次事物
            for (int seg = 0; (seg * Size) < RowCount; seg++)
            {
                //启用事物，把数据提交到内存，然后一次写入磁盘，提升批量操作性能
                IDataBaseHandler Handler = LocalDb.Handler;
                using (DbTransactionScope scope = new DbTransactionScope(Handler))
                {
                    try
                    {
                        int start = seg * Size;
                        int end = (seg + 1) * Size;
                        for (int i = start; i < end && i < RowCount; i++)
                        {
                            IList<Object> parameters = new List<Object>();
                            foreach(String colName in ColumnNames)
                            {
                                parameters.Add(DataRows[i][colName]);    
                            }
                            ParameterizedSQL PSQL = Handler.DbAdapter.AdaptSQLAnonymousParams(sql, parameters.ToArray());
                            rtn += Handler.ExecuteNonQuery(PSQL.SQL, PSQL.Parameters);
                        }
                        scope.Complete();
                    }
                    catch (Exception ex)
                    {
                        //事物回滚
                        scope.Dispose();
                        throw ex;
                    }
                }
            }
            return rtn;
        }
        /// <summary>
        /// 删除本地客户表中的记录,将临时数据表中的记录插入到客户表
        /// </summary>
        /// <returns></returns>
        public int TranslateCustomerData()
        {
            IDataBaseHandler Hander = LocalDb.Handler;
            using (DbTransactionScope scope = new DbTransactionScope(Hander))
            {
                try
                {
                    /*删除本地客户表中的记录
                    1、删除CustomID为空的记录
                    2、删除CustomID在临时表中的记录
                    * */
                    StringBuilder strSQL = new StringBuilder();
                    strSQL.Append("delete from Customs");
                    Hander.ExecuteNonQuery(strSQL.ToString());

                    DataTable TemplateDtCus = LocalDb.TableTemplates.Customers;
                    String colNames = "";
                    foreach (DataColumn col in TemplateDtCus.Columns)
                        colNames += col.ColumnName + ",";
                    colNames = colNames.TrimEnd(',');

                    String sql = "INSERT INTO Customs(" + colNames + ") SELECT " + colNames + " from CustomsTemp";
                    int rtn = Hander.ExecuteNonQuery(sql);
                    scope.Complete();
                    return rtn;
                }
                catch
                {
                    scope.Dispose();
                    throw;
                }
            }
        }
        /// <summary>
        /// 从配置文件中读取当前站点编号
        /// </summary>
        /// <returns></returns>
        private string GetSiteID()
        {
            String siteId = "";
            string siteName = GlobalObjects.GSetting.MachineSiteName;
            if (!String.IsNullOrEmpty(siteName))
            {
                siteId = SitesDAO.GetSiteIdByName(siteName);
            }
            LogUtils.WriteDebug(String.Format("获取本机所在站点,名称={0},ID={1}", siteName, siteId));
            return siteId;
        }
    }
}
